/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.foxinline.manager.criar;

import br.com.foxinline.enums.TipoDocumento;
import br.com.foxinline.enums.TipoProcesso;
import br.com.foxinline.enums.TipoSituacao;
import br.com.foxinline.modelo.*;
import br.com.foxinline.servico.*;
import br.com.foxinline.util.Msg;
import br.com.foxinline.utilitarios.ArquivoUtilitario;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;

/**
 *
 * @author laverson
 */
@ViewScoped
@ManagedBean
public class ManagerCriarProtocolo implements Serializable {

    @EJB
    PessoaServico pessoaServico;
    @EJB
    ProtocoloServico protocoloServico;
    @EJB
    AnexoServico anexoServico;
    @EJB
    UsuarioServico usuarioServico;
    @EJB
    SecretariaServico secretariaServico;
    private Protocolo protocolo;
    private Pessoa cliente;
    private Processo processo;
    private List<Processo> processos;
    private ArquivoUtilitario arquivoProtocolo = new ArquivoUtilitario();
    private static final String msgErroValidacao = ":: Erro de validação:";
    private static final String msgFailure = msgErroValidacao.concat(" o valor é necessário.");
    private List<Tramite> tramites;
    private Tramite tramite;
    private Secretaria secretaria;
    private Setor setor;
    private List<Setor> setores;
    private Usuario servidor;
    private List<Usuario> servidores;
    private List<Protocolo> protocolos;

    @PostConstruct
    public void init() {
        protocolo = new Protocolo();
        iniciarCliente();
        iniciarProcesso();
        processos = new ArrayList<Processo>();
        tramites = new ArrayList<Tramite>();
        tramite = new Tramite();
        secretaria = new Secretaria();
        setores = new ArrayList<Setor>();
        setor = new Setor();
        servidor = new Usuario();
        servidores = new ArrayList<Usuario>();
        protocolos = protocoloServico.findLimit(null);
    }

    public List<SelectItem> getTipoSituacao() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        for (TipoSituacao tipo : TipoSituacao.values()) {
            items.add(new SelectItem(tipo, tipo.getNome()));
        }
        return items;
    }

    public void addTramite() {
        try {

            tramite.setTransmitente(usuarioServico.getCurrentUser());
            if (tramite.getTransmitente().getSetor() != null) {
                tramite.setSecretaria(secretariaServico.find(tramite.getTransmitente().getSetor()));
            }
            tramite.setDataTransmitente(new Date());
            tramite.setPrazo(prazoData());

            tramites.add(tramite);
            tramite = new Tramite();
        } catch (Exception erro) {
        }
    }

    public void removerTramite(Tramite tramite) {
        tramites.remove(tramite);
    }

    public Date prazoData() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_YEAR, 15);
        return c.getTime();
    }

    public void salvar() {
        try {
            if (protocoloValido()) {
                arquivoProtocolo.gravarAnexosDoProcesso(processos);
                protocolo.setProcessos(processos);

                addTramite();

                protocolo.setTramites(tramites);
                protocolo.setDataCadastro(new Date());
                protocolo.setDataProtocolo(new Date());
                protocolo.setCliente(cliente);
                protocoloServico.salvar(protocolo);
                Msg.messagemInfo(Msg.SuccessFull);
                init();
            } else {
                RequestContext.getCurrentInstance().execute("requiredCredor(true)");
            }
        } catch (EJBException e) {
            Exception causedByException = e.getCausedByException();
            if (!(causedByException instanceof javax.validation.ConstraintViolationException)) {
                Msg.messagemWarn("Número".concat(msgErroValidacao).concat(" número do protocolo já existe"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            Msg.messagemError(Msg.Failure);
        }
    }

    public void existeCliente() {
        Pessoa p = pessoaServico.existProprietario(cliente);

        if (p != null) {
            cliente = p;
        } else {
            cliente.setId(null);
        }
    }

    public List<SelectItem> getTipoDocumento() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        for (TipoDocumento tipo : TipoDocumento.values()) {
            items.add(new SelectItem(tipo, tipo.getNome()));
        }
        return items;
    }

    public List<SelectItem> getTipoProcesso() {
        List<SelectItem> items = new ArrayList<SelectItem>();
        for (TipoProcesso tipo : TipoProcesso.values()) {
            items.add(new SelectItem(tipo, tipo.getNome()));
        }
        return items;
    }
    private static int tamanhoMaximoNome = 10;

    public String nomeAnexo(Anexo a) {
        if (a.getNomeExibicao().length() >= tamanhoMaximoNome) {
            return a.getNomeExibicao().substring(0, tamanhoMaximoNome).concat("...");
        }
        return a.getNomeExibicao().replace(".png", "").replace(" ", "_");
    }

    public String nomeAnexoPdf(Anexo a) {
        if (a.getNomeExibicao().length() >= tamanhoMaximoNome) {
            return a.getNomeExibicao().substring(0, tamanhoMaximoNome).concat("...");
        }
        return a.getNomeExibicao().replace(".pdf", "").replace(" ", "_");
    }

    public void handleAnnex(FileUploadEvent event) throws IOException {
        try {
            processo.getAnexos().add(arquivoProtocolo.adicionarArquivo(event));
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ManagerCriarProtocolo.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(ManagerCriarProtocolo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Remove o anexo da lista de anexos do processo que está sendo adicionado e
     * remove o arquivo do diretório que foi gravado
     *
     * @param anexo
     */
    public void removerAnexo(Anexo anexo) {
        try {
            arquivoProtocolo.excluirArquivo(new File(anexo.getUrl() + anexo.getNome()));
            processo.getAnexos().remove(anexo);
        } catch (Exception e) {
            Msg.messagemError(Msg.Failure);
        }
    }

    public void adicionarProcesso() {
        if (processoValido()) {
            if (!processos.contains(processo)) {
                processos.add(processo);
            }
            iniciarProcesso();
        } else {
            RequestContext.getCurrentInstance().execute("required(true)");
        }
    }

    public void editarProcesso(Processo p) {
        processo = p;
        processos.remove(p);
    }

    public void removerProcesso(Processo p) {
        processos.remove(p);
    }

    private boolean processoValido() {

        if (isProcessoRequerimento() || isProcessoReciboPagamento()) {
            if (processo.getObjeto() == null || processo.getObjeto().equals("")) {
                Msg.messagemError("Objeto".concat(msgFailure));
                return false;
            }
        }
        if (isProcessoAutorizacao()) {
            if (processo.getNumeroProcessoAdministrativo() == null) {
                Msg.messagemError("Nº Processo Administrativo".concat(msgFailure));
            }
            if (processo.getNumeroServico() == null) {
                Msg.messagemError("Nº Serviço".concat(msgFailure));
            }
            if (processo.getNumeroRequisicao() == null) {
                Msg.messagemError("Nº Requisição".concat(msgFailure));
            }
            if (processo.getNumeroProcessoAdministrativo() == null || processo.getNumeroServico() == null || processo.getNumeroRequisicao() == null) {
                return false;
            }
        }
        if (isProcessoEmpenho()) {
            if (processo.getNumeroNotaEmpenho() == null) {
                Msg.messagemError("Nota de Empenho".concat(msgFailure));
                return false;
            }
        }
        if (isProcessoNotaLiquidacao() || isProcessoPagamento()) {
            if (processo.getValorLiquidacao() == null) {
                Msg.messagemError("Valor".concat(msgFailure));
                return false;
            }
        }
        return true;
    }

    private boolean protocoloValido() {
        if (isPessoaFisica()) {
            if (cliente.getCpf() == null || cliente.getCpf().equals("")) {
                Msg.messagemError("CPF".concat(msgFailure));
            }
            if (cliente.getNome() == null || cliente.getNome().equals("")) {
                Msg.messagemError("Nome".concat(msgFailure));
            }
            if ((cliente.getCpf() == null || cliente.getCpf().equals("")) || (cliente.getNome() == null || cliente.getNome().equals(""))) {
                return false;
            }
        } else {
            if (cliente.getCnpj() == null || cliente.getCnpj().equals("")) {
                Msg.messagemError("CPF".concat(msgFailure));
            }
            if (cliente.getNomeFantasia() == null || cliente.getNomeFantasia().equals("")) {
                Msg.messagemError("Nome".concat(msgFailure));
            }
            if ((cliente.getCnpj() == null || cliente.getCnpj().equals("")) || (cliente.getNomeFantasia() == null || cliente.getNomeFantasia().equals(""))) {
                return false;
            }
        }
        return true;
    }

    public void iniciarCliente() {
        cliente = new Pessoa();
        cliente.setTipoDocumento(TipoDocumento.CPF);
    }

    public void iniciarProcesso() {
        processo = new Processo();
        processo.setAnexos(new ArrayList<Anexo>());
        processo.setTipoProcesso(TipoProcesso.REQUERIMENTO);
    }

    public boolean isPessoaFisica() {
        return cliente.getTipoDocumento().equals(TipoDocumento.CPF);
    }

    public boolean isProcessoRequerimento() {
        return processo.getTipoProcesso().equals(TipoProcesso.REQUERIMENTO);
    }

    public boolean isProcessoAutorizacao() {
        return processo.getTipoProcesso().equals(TipoProcesso.AUTORIZACAO_COMPRA_SERVICO);
    }

    public boolean isProcessoEmpenho() {
        return processo.getTipoProcesso().equals(TipoProcesso.EMPENHO);
    }

    public boolean isProcessoReciboPagamento() {
        return processo.getTipoProcesso().equals(TipoProcesso.RECIBO_PAGAMENTO);
    }

    public boolean isProcessoNotaLiquidacao() {
        return processo.getTipoProcesso().equals(TipoProcesso.NOTA_LIQUIDACAO);
    }

    public boolean isProcessoComprovante() {
        return processo.getTipoProcesso().equals(TipoProcesso.COMPROVANTE_TRANSFERENCIA);
    }

    public boolean isProcessoPagamento() {
        return processo.getTipoProcesso().equals(TipoProcesso.PAGAMENTO_BAIXA);
    }

    public Protocolo getProtocolo() {
        return protocolo;
    }

    public void setProtocolo(Protocolo protocolo) {
        this.protocolo = protocolo;
    }

    public Pessoa getCliente() {
        return cliente;
    }

    public void setCliente(Pessoa cliente) {
        this.cliente = cliente;
    }

    public Processo getProcesso() {
        return processo;
    }

    public void setProcesso(Processo processo) {
        this.processo = processo;
    }

    public List<Processo> getProcessos() {
        return processos;
    }

    public void setProcessos(List<Processo> processos) {
        this.processos = processos;
    }

    public List<Tramite> getTramites() {
        return tramites;
    }

    public void setTramites(List<Tramite> tramites) {
        this.tramites = tramites;
    }

    public Tramite getTramite() {
        return tramite;
    }

    public void setTramite(Tramite tramite) {
        this.tramite = tramite;
    }

    public Setor getSetor() {
        return setor;
    }

    public void setSetor(Setor setor) {
        this.setor = setor;
    }

    public List<Setor> getSetores() {
        return setores;
    }

    public void setSetores(List<Setor> setores) {
        this.setores = setores;
    }

    public Usuario getServidor() {
        return servidor;
    }

    public void setServidor(Usuario servidor) {
        this.servidor = servidor;
    }

    public List<Usuario> getServidores() {
        return servidores;
    }

    public void setServidores(List<Usuario> servidores) {
        this.servidores = servidores;
    }

    public Secretaria getSecretaria() {
        return secretaria;
    }

    public void setSecretaria(Secretaria secretaria) {
        this.secretaria = secretaria;
    }

    public List<Protocolo> getProtocolos() {
        return protocolos;
    }

    public void setProtocolos(List<Protocolo> protocolos) {
        this.protocolos = protocolos;
    }
}
